package com.lingjtx.auth.controller;

import com.lingjtx.common.captcha.*;
import com.lingjtx.common.core.ResponseResult;
import com.lingjtx.common.core.annotation.IgnoreLogin;
import com.lingjtx.common.core.constant.Const;
import com.lingjtx.common.core.util.StringUtil;
import com.lingjtx.common.redis.service.IRedisService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Objects;

@Controller
@RequestMapping("/captcha")
public class CaptchaController {

    private final IRedisService redisService;

    public CaptchaController(IRedisService redisService) {
        this.redisService = redisService;
    }

    @IgnoreLogin
    @ResponseBody
    @GetMapping("/image/{type}/{uid}")
    public void image(@PathVariable("type") String type, @PathVariable("uid") String uid, HttpServletResponse response) throws IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0L);
        String rdsKey = String.format(CaptchaHandle.REDIS_CAPTCHA_KEY, uid);
        CaptchaVo captcha = (CaptchaVo) redisService.get(rdsKey);
        if (Objects.nonNull(captcha)) {
            if ("bg".equals(type)) {
                response.setContentType("image/jpeg");
                response.getOutputStream().write(captcha.getBgByteStream());
            } else {
                response.setContentType("image/apng");
                response.getOutputStream().write(captcha.getMvByteStream());
            }
            response.getOutputStream().flush();
        }
    }

    @IgnoreLogin
    @ResponseBody
    @GetMapping("/verify_code")
    public void verifyCode(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0L);
        response.setContentType("image/jpeg");
        // 生成随机字串
        String verifyCode = VerifyCode.generateVerifyCode(4);
        redisService.set("captcha:verify:code:" + request.getSession().getId(), verifyCode, 2 * 60);
        // 生成图片
        int w = 90, h = 50;
        try {
            VerifyCode.outputImage(w, h, response.getOutputStream(), verifyCode);
        } catch (Exception e) {
        }
    }

    @IgnoreLogin
    @ResponseBody
    @PostMapping("/create")
    public ResponseResult<CaptchaVo> createCaptcha(@RequestBody CaptchaPo model) {
        if (StringUtil.isEmpty(model.getCaptchaType())) {
            return ResponseResult.createByError("验证码类型 captchaType 不为空！");
        }
        CaptchaType type = CaptchaType.parseFromValue(model.getCaptchaType());
        CaptchaVo captcha = CaptchaGenerator.generator(type, redisService);
        return ResponseResult.createBySuccess(captcha);
    }

    @IgnoreLogin
    @ResponseBody
    @PostMapping("/check")
    public ResponseResult<CaptchaVo> check(@RequestBody CaptchaPo model) {
        if (StringUtil.isEmpty(model.getCaptchaType())
                || StringUtil.isEmpty(model.getCaptchaUid())
                || StringUtil.isEmpty(model.getPointJson())) {
            return ResponseResult.createByError("验证码类型 captchaType 或 captchaUid 或点坐标位置不为空！");
        }
        CaptchaType type = CaptchaType.parseFromValue(model.getCaptchaType());
        String key = CaptchaGenerator.valid(type, model.getCaptchaUid(), model.getPointJson(), redisService);
        if (StringUtil.isNotEmpty(key)) {
            CaptchaVo captcha = new CaptchaVo();
            captcha.setCaptchaType(model.getCaptchaType());
            captcha.setCaptchaUid(model.getCaptchaUid());
            captcha.setAuthenticate(key);
            return ResponseResult.createBySuccess(captcha);
        }
        return ResponseResult.createByError("验证失败，请重试");
    }

    @IgnoreLogin
    @GetMapping(value = "/h5/{captchaType}", produces = "text/html")
    public String web(@PathVariable("captchaType") String captchaType,
                      HttpServletRequest request,
                      Model model) {
        model.addAttribute("captchaType", captchaType);
        model.addAttribute("pubKey", Const.RSA_PUB_KEY);
        model.addAttribute("baseUrl", Const.SERVER_URL);
        model.addAttribute("redirectUrl", request.getParameter("cb"));
        return "captcha";
    }
}
